//
//  UpdateBookingViewController.m
//  mUBB
//
//  Created by Cosmin Stirbu on 3/6/13.
//  Copyright (c) 2013 Cosmin Stirbu. All rights reserved.
//

#import "UpdateBookingViewController.h"
#import "CenteredTextCell.h"
#import "UIViewAdditions.h"
#import "KalDate.h"
#import "Constants.h"
#import "CustomPickerView.h"
#import "RoomSelectionViewController.h"
#import "TypeOfClassViewController.h"
#import "CoursesManager.h"
#import "StudyGroupsViewController.h"
#import "BookingsManager.h"
#import "WSError.h"

#define DELETE_BOOKING_ALERT_TAG 1
#define UPDATE_BOOKING_ALERT_TAG 2
#define ADD_BOOKING_ALERT_TAG 3

#define DATE_FORMAT @"EE dd - MMM - yyyy"
#define TIME_FORMAT @"HH:mm"

#define KAL_VIEW_Y (IS_IPAD () ? 136 : 45)
#define KAL_VIEW_WIDTH (IS_IPAD () ? 420 : 320)
#define KAL_VIEW_HEIGHT (IS_IPAD () ? 295 : 266)

@interface UpdateBookingViewController ()

@end

@implementation UpdateBookingViewController

@synthesize delegate, updatingBooking, bookingTableView;

- (id)initWithNibName:(NSString *)nibNameOrNil booking:(Booking *)booking course:(Course *)course
{
    self = [super initWithNibName:nibNameOrNil bundle:nil];
    if (self) {
        // Custom initialization
        if (booking) {
            _booking = [Booking bookingWithBooking:booking];
            _selectedStartTime = _booking.startDate;
            _selectedEndTime = _booking.endDate;
        } else {
            _booking = [Booking new];
        }
        if (course != nil) {
            _booking.course = course;
        }
        _selectedDate = _booking.startDate;
        if (_selectedDate == nil) {
            _selectedDate = [NSDate date];
            _selectedStartTime = _selectedDate;
        }
        
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    // Set up the UI
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"ALERT_OK", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(doneButtonPressed:)];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:YES];
    [self okPressedOnCalView:nil];
    [_timePickerView dismissPickerView];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [bookingTableView reloadData];
}

#pragma mark - Custom Setter For UpdatingBooking

- (void)setUpdatingBooking:(BOOL)_updatingBooking {
    updatingBooking = _updatingBooking;
    if (updatingBooking) {
        _numberOfSections = 8;
        _startTimeWasSet = YES;
        _endTimeWasSet = YES;
    } else {
        _numberOfSections = 7;
    }
}

#pragma mark - UITableViewDataSource Methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return _numberOfSections;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    switch (section) {
        case 0:
            return NSLocalizedString(@"BOOKING_DATE", nil);
            break;
        case 1:
            return NSLocalizedString(@"START_TIME", nil);
            break;
        case 2:
            return NSLocalizedString(@"END_TIME", nil);
            break;
        case 3:
            return NSLocalizedString(@"BOOKING_CELL_PLACE", nil);
            break;
        case 4:
            return NSLocalizedString(@"BOOKING_CELL_STUDY_GROUPS", nil);
            break;
        case 5:
            return NSLocalizedString(@"BOOKING_TYPE_OF_CLASS", nil);
            break;
    }
    return nil;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    switch (section) {
        case 4:
            return 1 + [_booking.studyGroups count];
        default:
            return 1;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    CenteredTextCell *cell = [bookingTableView dequeueReusableCellWithIdentifier:@"CenteredCell"];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CenteredTextCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }
    NSString *cellTitle = NSLocalizedString(@"SELECT", nil);
    switch (indexPath.section) {
        case 0: {
                cellTitle = [Utils stringFromDate:_selectedDate withFormat:DATE_FORMAT];
            break;
        }
        case 1: {
            if (_startTimeWasSet)
                cellTitle = [Utils stringFromDate:_selectedStartTime withFormat:TIME_FORMAT];
            break;
        }
        case 2: {
            if (_endTimeWasSet)
                cellTitle = [Utils stringFromDate:_selectedEndTime withFormat:TIME_FORMAT];
            break;
        }
        case 3: {
            if (_booking.room)
                cellTitle = [NSString stringWithFormat:@"%@, %@",_booking.room.name, _booking.room.building.name];
            break;
        }
        case 4 :{
            if (indexPath.row < [_booking.studyGroups count]) {
                StudyGroup *studyGroup = [_booking.studyGroups objectAtIndex:indexPath.row];
                cellTitle = studyGroup.name;
            }
            break;
        }
        case 5: {
            if (_booking.typeOfClass) {
                cellTitle = _booking.typeOfClass.name;
            }
            break;
        }
        case 6: {
            if (updatingBooking) {
                cellTitle = NSLocalizedString(@"UPDATE_BOOKING", nil);
            } else {
                cellTitle = NSLocalizedString(@"ADD_BOOKING_TITLE", nil);
            }
            break;
        }
        default: {
            cellTitle = NSLocalizedString(@"DELETE_BOOKING", nil);
            break;
        }
    }
    cell.centeredLabel.text = cellTitle;
    return cell;
}


#pragma mark - UITableViewDelegate methods

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 4 && indexPath.row < [_booking.studyGroups count]) {
        return UITableViewCellEditingStyleDelete;
    } else {
        return UITableViewCellEditingStyleNone;
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [bookingTableView setEditing:NO animated:NO];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    switch (indexPath.section) {
        case 0:
            [self presentCalendar];
            break;
        case 1:{
            _isStartTime = YES;
            [self presentTimePicker];
            break;
        }
        case 2: {
            _isStartTime = NO;
            [self presentTimePicker];
            _timePickerView.timePickerView.minimumDate = _booking.startDate;
            break;
        }
        case 3: {
            RoomSelectionViewController *roomsSelection = [[RoomSelectionViewController alloc] initWithNibName:@"RoomSelectionViewController" booking:_booking];
            roomsSelection.title = NSLocalizedString(@"ROOM_SELECTION_TITLE", nil);
            [self.navigationController pushViewController:roomsSelection animated:YES];
            break;
        }
        case 4: {
            if (indexPath.row == [_booking.studyGroups count]) {
                StudyGroupsViewController *studyGroups = [[StudyGroupsViewController alloc] initWithNibName:@"StudyGroupsViewController" booking:_booking];
                studyGroups.title = NSLocalizedString(@"STUDY_GROUPS_TITLE", nil);
                [self.navigationController pushViewController:studyGroups animated:YES];
            } else {
                [bookingTableView setEditing:YES animated:NO];
            }
            break;
        }
        case 5: {
            TypeOfClassViewController *typeOfClassVC = [[TypeOfClassViewController alloc] initWithNibName:@"TypeOfClassViewController" booking:_booking];
            typeOfClassVC.title = NSLocalizedString(@"TYPE_OF_CLASS_TITLE", nil);
            [self.navigationController pushViewController:typeOfClassVC animated:YES];
            break;
            
        }
        case 6: {
            // Check if add button
            if (!updatingBooking) {
                [self addBooking];
            } else {
                [self updateBooking];
            }
            break;
        }
        case 7: {
            // Delete Booking
            [self deleteBooking];
            break;
        }
        default:
            break;
    }
}


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    [_booking.studyGroups removeObjectAtIndex:indexPath.row];
    [bookingTableView setEditing:NO animated:NO];
    [bookingTableView reloadData];
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 7) {
        cell.backgroundColor = [UIColor redColor];
    } else if (indexPath.section == 6) {
        cell.backgroundColor = [UIColor greenColor];
    } else {
        cell.backgroundColor = [UIColor whiteColor];
    }
}
#pragma mark - UI Interaction

- (void)doneButtonPressed:(id)sender {
    [delegate didFinishUpdatingBooking:self refreshBookings:NO];
}

- (IBAction)okPressedOnCalView:(id)sender {
    UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
    [[mainWindow viewWithTag:1] setUserInteractionEnabled:YES];
    [UIView animateWithDuration:0.3
                     animations:^(void)  {
                         calendarPopOver.top = mainWindow.bottom;
                     } completion:^(BOOL finished) {
                         [calendarPopOver removeFromSuperview];
                     }];
}

#pragma mark - Private Methods

- (void)presentCalendar {
    // We will init the logic and the kalView every time deliveryDateButton is pressed and we will release them when the OK button on the calendarPopOver is pressed
    if (kalView == nil) {
        NSDate *selectedDate = _booking.startDate;
        if (selectedDate == nil) {
            selectedDate = [NSDate date];
        }
        logic = [[KalLogic alloc] initForDate:selectedDate];
        kalView = [[KalView alloc] initWithFrame:CGRectMake(0, KAL_VIEW_Y, KAL_VIEW_WIDTH, KAL_VIEW_HEIGHT) delegate:self logic:logic allDays:NO];
    }
    
    if (!IS_IPAD()) {
        // Lock the PanelViewController and animate the calendarPopOver up
        [calendarPopOver addSubview:kalView];
        UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
        [[mainWindow viewWithTag:1] setUserInteractionEnabled:NO];
        
        [mainWindow addSubview:calendarPopOver];
        calendarPopOver.top = mainWindow.bottom;
        
        [UIView animateWithDuration:0.3
                         animations:^(void)  {
                             calendarPopOver.top -= calendarPopOver.height;
                         }];
    } else {
        // iPad
        UIViewController *viewController = [UIViewController new];
        kalView.top = 0;
        kalView.autoresizingMask = UIViewAutoresizingNone;
        [viewController.view addSubview:kalView];
        viewController.view.backgroundColor = [Utils colorWithHexString:[[ConfigurationManager instance] UIConfigValueForKey:@"calendar_background_color"]];
        viewController.contentSizeForViewInPopover = CGSizeMake(kalView.width, kalView.height + 28);
        ipadPopOverController = [[UIPopoverController alloc] initWithContentViewController:viewController];
        ipadPopOverController.popoverContentSize = CGSizeMake(kalView.width, kalView.height + 28);
        [ipadPopOverController presentPopoverFromRect:[bookingTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]].frame inView:bookingTableView permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    }
}

- (void)presentTimePicker {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomPickerView" owner:self options:nil];
    _timePickerView = [nib objectAtIndex:0];
    if (!IS_IPAD()) {
        [_timePickerView presentPickerViewFromView:self.view];
    } else {
        UIViewController *viewController = [UIViewController new];
        _timePickerView.timePickerView.top = 0;
        [viewController.view addSubview:_timePickerView.timePickerView];
        ipadPopOverController = [[UIPopoverController alloc] initWithContentViewController:viewController];
        ipadPopOverController.popoverContentSize = _timePickerView.timePickerView.frame.size;
        if (_isStartTime) {
            [ipadPopOverController presentPopoverFromRect:[bookingTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]].frame inView:bookingTableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }
        else {
            [ipadPopOverController presentPopoverFromRect:[bookingTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]].frame inView:bookingTableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }
        ipadPopOverController.delegate = self;
    }
    if (_isStartTime) {
        _timePickerView.timePickerView.date = _selectedDate;
    } else {
        _timePickerView.timePickerView.date = _selectedStartTime;
        _timePickerView.timePickerView.minimumDate = _selectedStartTime;
    }
    _timePickerView.delegate = self;
}

- (void)deleteBooking {
    [Utils showLoadingOn:self];
    [self.navigationController.view setUserInteractionEnabled:YES];
    [[BookingsManager instance] deleteBooking:_booking delegate:self];
}

- (void)updateBooking {
    if ([self validateBooking]) {
        [Utils showLoadingOn:self];
        [self.navigationController.view setUserInteractionEnabled:YES];
        [[BookingsManager instance] updateBooking:_booking delegate:self];
    }
}

- (void)addBooking {
    if ([self validateBooking]) {
        [Utils showLoadingOn:self];
        [self.navigationController.view setUserInteractionEnabled:YES];
        [[BookingsManager instance] createBooking:_booking delegate:self];
    }
}

- (BOOL)validateBooking {
    _booking.startDate = [Utils dateTimeFromDate:_selectedDate time:_selectedStartTime];
    _booking.endDate = [Utils dateTimeFromDate:_selectedDate time:_selectedEndTime];
    NSString *message = nil;
    if (!_startTimeWasSet) {
        message = NSLocalizedString(@"PLEASE_SELECT_START_TIME", nil);
    } else if (!_endTimeWasSet) {
        message = NSLocalizedString(@"PLEASE_SELECT_END_TIME", nil);
    } else if ([_booking.startDate compare:_booking.endDate] == NSOrderedDescending) {
        message = NSLocalizedString(@"START_TIME_GREATER_THAN_END_TIME", nil);
    }
    else if ([_booking.startDate compare:_booking.endDate] == NSOrderedDescending) {
        message = NSLocalizedString(@"START_TIME_END_TIME_SAME", nil);
    } else if (_booking.room == nil) {
        message = NSLocalizedString(@"PLEASE_SELECT_ROOM", nil);
    } else if ([_booking.studyGroups count] == 0) {
        message = NSLocalizedString(@"PLEASE_SELECT_STUDY_GROUP", nil);
    } else if (_booking.typeOfClass == nil) {
        message = NSLocalizedString(@"PLEASE_SELECT_TYPE_OF_CLASS", nil);
    }
    if (message != nil) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"ALERT_OK", nil) otherButtonTitles:nil];
        [alert show];
        return NO;
    }
    return YES;
}
#pragma mark - Kal View Delegate Methods

- (void)didSelectDate:(KalDate *)date {
    _selectedDate = date.NSDate;
    [bookingTableView reloadData];
}

- (void)showFollowingMonth {
    [logic advanceToFollowingMonth];
    [kalView slideDown];
}

- (void)showPreviousMonth {
    [logic retreatToPreviousMonth];
    [kalView slideUp];
}

#pragma mark - UIDatePicker Delegate

- (void)didDismissPickerView {
    [self setTimes];
}

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
    [self setTimes];
}

- (void)setTimes {
    if (_isStartTime) {
        _selectedStartTime = _timePickerView.timePickerView.date;
        _startTimeWasSet = YES;
    } else {
        _selectedEndTime = _timePickerView.timePickerView.date;
        _endTimeWasSet = YES;
    }
    [bookingTableView reloadData];
}

#pragma mark - BookingsProtocol Methods

- (void)didDeleteBookingWithSuccess:(id)object forTicket:(Ticket *)ticket {
    [Utils hideLoadingOn:self];
    [self.navigationController.view setUserInteractionEnabled:YES];
    if (!_isOnScreen) {
        return;
    }
    [[BookingsManager instance] deleteBookingFromCalendar:_booking];
    [delegate didFinishUpdatingBooking:self refreshBookings:YES];
}


- (void)didDeleteBookingWithFailure:(id)object forTicket:(Ticket *)ticket {
    [Utils hideLoadingOn:self];
    [self.navigationController.view setUserInteractionEnabled:YES];
    if (!_isOnScreen) {
        return;
    }
    WSError *error = (WSError *)object;
    if (error.errorCode == StatusCodeConnectionError) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:self cancelButtonTitle:NSLocalizedString(@"ALERT_CANCEL", nil) otherButtonTitles:NSLocalizedString(@"ALERT_RETRY", nil), nil];
        alertView.tag = DELETE_BOOKING_ALERT_TAG;
        [alertView show];
    } else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:nil cancelButtonTitle:NSLocalizedString(@"ALERT_OK", nil) otherButtonTitles: nil];
        [alertView show];
    }
}

- (void)didUpdateBookingWithSuccess:(id)object forTicket:(Ticket *)ticket {
    [Utils hideLoadingOn:self];
    [self.navigationController.view setUserInteractionEnabled:YES];
    if (!_isOnScreen) {
        return;
    }
    [[BookingsManager instance] deleteBookingFromCalendar:_booking];
    [delegate didFinishUpdatingBooking:self refreshBookings:YES];
}

- (void)didUpdateBookingWithFailure:(id)object forTicket:(Ticket *)ticket {
    [Utils hideLoadingOn:self];
    [self.navigationController.view setUserInteractionEnabled:YES];
    if (!_isOnScreen) {
        return;
    }
    WSError *error = (WSError *)object;
    if (error.errorCode == StatusCodeConnectionError) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:self cancelButtonTitle:NSLocalizedString(@"ALERT_CANCEL", nil) otherButtonTitles:NSLocalizedString(@"ALERT_RETRY", nil), nil];
        alertView.tag = UPDATE_BOOKING_ALERT_TAG;
        [alertView show];
    } else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:nil cancelButtonTitle:NSLocalizedString(@"ALERT_OK", nil) otherButtonTitles: nil];
        [alertView show];
    }
}

- (void)didCreateBookingWithSuccess:(id)object forTicket:(Ticket *)ticket {
    [Utils hideLoadingOn:self];
    [self.navigationController.view setUserInteractionEnabled:YES];
    if (!_isOnScreen) {
        return;
    }
    [delegate didFinishUpdatingBooking:self refreshBookings:YES];
}

- (void)didCreateBookingWithFailure:(id)object forTicket:(Ticket *)ticket {
    [Utils hideLoadingOn:self];
    [self.navigationController.view setUserInteractionEnabled:YES];
    if (!_isOnScreen) {
        return;
    }
    WSError *error = (WSError *)object;
    if (error.errorCode == StatusCodeConnectionError) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:self cancelButtonTitle:NSLocalizedString(@"ALERT_CANCEL", nil) otherButtonTitles:NSLocalizedString(@"ALERT_RETRY", nil), nil];
        alertView.tag = ADD_BOOKING_ALERT_TAG;
        [alertView show];
    } else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:nil cancelButtonTitle:NSLocalizedString(@"ALERT_OK", nil) otherButtonTitles: nil];
        [alertView show];
    }
    
}

#pragma mark - UIAlertViewDelegate Methods
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex != alertView.cancelButtonIndex) {
        switch (alertView.tag) {
            case DELETE_BOOKING_ALERT_TAG:
                [self deleteBooking];
                break;
            case UPDATE_BOOKING_ALERT_TAG:
                [self updateBooking];
                break;
            case ADD_BOOKING_ALERT_TAG:
                [self addBooking];
                break;
            default:
                break;
        }
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewDidUnload {
    [self setBookingTableView:nil];
    calendarPopOver = nil;
    [super viewDidUnload];
}
@end
